package kjd;

import robocode.Robot;
import robocode.util.Utils;
import robocode.HitByBulletEvent;
import robocode.HitRobotEvent;
import robocode.HitWallEvent;
import robocode.BulletHitEvent;
import robocode.ScannedRobotEvent;
import java.awt.Color;

/**
 * Creates a robot designed to beat 8 sample robots. Designed to beat Walls, Crazy, RamFire,
 * SpinBot, Corners, SittingDuck, Tracker, and Fire. Modifed by version.subversion.date.
 * 
 * @author Kendyll Doi
 */
public class GunAryos extends Robot {
  private double rotation = Utils.normalRelativeAngleDegrees(Math.random() * 360);

  // random variable turning angle.

  /**
   * Runs main operation.
   */
  public void run() {
    // sets custom color set to individualize robot.
    setBodyColor(new Color(255, 150, 0));
    setGunColor(Color.WHITE);
    setRadarColor(new Color(255, 150, 0));
    setScanColor(new Color(0, 200, 0));
    setBulletColor(Color.PINK);
    // constantly repeats actions.
    // turns in a direction and runs for the next wall to evade shots.
    while (true) {
      turnRight(Utils.normalRelativeAngleDegrees(rotation));
      // 5000 used as distance beyond most borders, motion is fast and far.
      ahead(5000);
    }
  }

  /**
   * Fires high power bullet when it scans a robot. High power has greatest reward and most damage.
   * 
   * @param e is the event of a scanned opponent robot and its statistics.
   */
  public void onScannedRobot(ScannedRobotEvent e) {
    fire(3);
    if (e.getDistance() < 50) {
      stop();
      rotation = 0;
      ahead(50);
    }
    // scans again as to allow a chance to fire immediately without returning to pattern.
    scan();
  }

  /**
   * Assigns random rotation value away from impacted wall on impact with wall. Prevents bot from
   * stick to wall too much.
   * 
   * @param e is the event which a wall is hit.
   */
  public void onHitWall(HitWallEvent e) {
    rotation = Utils.normalRelativeAngleDegrees(e.getBearing() + 180 + Math.random() * 90);
  }

  /**
   * Turns robot towards impacted robot and fires if caused impact. If caused impact, will rush
   * forward in attempt to ram robot and fire ahead attempting to hit robot immediately.
   * 
   * @param e is the event which a robot is hit.
   */
  public void onHitRobot(HitRobotEvent e) {
    turnRight(Utils.normalRelativeAngleDegrees(e.getBearing()));

    if (Math.abs(e.getBearing()) < 5) {
      fire(3);
    }
    ahead(40);
    rotation = Utils.normalRelativeAngleDegrees(e.getBearing());
    // scans again as to override initial rotation making firing continuously is possible.
    scan();
  }

  /**
   * Turns robot if already moving to evade any continuous fire. Will only rotate extra if in motion
   * preventing awkward rotation at walls. Evades if robot is not dead ahead. Only time rotation and
   * movement occur in Robot.
   * 
   * @param e is the event generated when hit by a bullet.
   */
  public void onHitByBullet(HitByBulletEvent e) {
    // scans to see if robot is dead ahead. This allows it to fire without rotating.
    scan();
    if (getVelocity() != 0 && Math.abs(e.getBearing()) > 5) {
      if (Math.abs(e.getBearing()) < 90) {
        turnRight(45 + Math.random() * 45);
      }
      else {
        turnLeft(45 + Math.random() * 45);
      }
    }
  }

  /**
   * Turns robot parallel to bullet which hit which hit opponent robot. Adds further movement and a
   * chance to realign with opponent.
   * 
   * @param e is the event generated when a bullet fired hits an opponent.
   */
  public void onBulletHit(BulletHitEvent e) {
    turnRight(Utils.normalRelativeAngleDegrees(e.getBullet().getHeading() - getHeading()));
  }
}
